<template>
  <div
    v-show="mappingProps.visible"
    v-html="result"
    :data-color-scheme="mappingProps.colorScheme"
    class="q-pa-md t-markdown markdown-body"
    :class="{
      'teld-theme-link': mappingProps.isTeldThemeLink,
    }"
  >
  </div>
</template>

<script setup lang="ts" name="TMarkdown">
import {
  computed,
  defineExpose,
  defineProps,
  ref,
  watch,
  watchEffect,
} from 'vue';
//
// import { Marked } from 'marked';
import MarkdownIt from 'markdown-it';
import hljs from 'highlight.js';
import colorful from 'markdown-it-colorful';
//
import useEnv from 't/common/hooks/useEnv';
import useMappingProps from 't/common/hooks/useMappingProps';
import { commonProps } from 't/common/utils';
import myProps from './props.js';
import { CODE_THEME, COLOR_SCHEME, VALUE_TYPE } from './constants.js';

// markdown基本样式，区分light和dark
import './styles/github-markdown.css';
// 自定义样式
import './styles/custom.scss';
// 代码块样式
import './styles/github.scss';
import './styles/github-dark.scss';

const props = defineProps({
  ...commonProps,
  ...myProps,
});

const toExpose = {};
const [mappingProps, mappingExpose] = useMappingProps(props, toExpose);

const isDesignMode = computed(() => useEnv().inDesign);
const codeTheme = computed(() => {
  return CODE_THEME[mappingProps.codeColorScheme] || CODE_THEME[COLOR_SCHEME.Light];
})

const result = ref('');

// const marked = new Marked({
//   async: true,
//   pedantic: false,
//   gfm: true,
// });
// 自定义渲染器
// const renderer = new marked.Renderer();
// renderer.code = function (token) {
//   const lang = hljs.getLanguage(token.lang) ? token.lang : 'plaintext';
//   const highlighted = hljs.highlight(token.text, { language: lang }).value;

//   return `<pre class="code-theme--${codeTheme.value}"><code class="hljs language-${lang}">${highlighted}</code></pre>`;
// };
// marked.setOptions({
//   renderer,
// });

const md = MarkdownIt({
  html: mappingProps.enableHtml,
  linkify: true,
  typographer: true,
  highlight: function (str, lang) {
    lang = hljs.getLanguage(lang) ? lang : 'plaintext';
    const highlighted = hljs.highlight(str, { language: lang }).value;

    return `
<pre class="code-theme--${codeTheme.value}">
  <code class="hljs language-${lang}"
  >${highlighted}</code>
</pre>
    `.trim();
  }
});

// 注册自定义插件
md.use(colorful, {
  color: mappingProps.highlightColor,
  bgColor: mappingProps.highlightBgColor,
  stillRenderTag: false,
});

const rawContent = computed(() => {
  if (mappingProps.valueType === VALUE_TYPE.Static) {
    return mappingProps.staticValue;
  }
  // expression 且设计模式下，使用 mockValue
  else if (isDesignMode.value) {
    return mappingProps.mockValue;
  }

  return mappingProps.exprValue;
});

watch(
  () => mappingProps.codeColorScheme,
  async () => {
    // result.value = await marked.parse(rawContent.value);
    result.value = md.render(rawContent.value);
  },
);

watch(
  () => mappingProps.highlightColor,
  async () => {
    colorful.set({'color': mappingProps.highlightColor});
    result.value = md.render(rawContent.value);
  },
);
watch(
  () => mappingProps.highlightBgColor,
  async () => {
    colorful.set({'bgColor': mappingProps.highlightBgColor});
    result.value = md.render(rawContent.value);
  },
);

watch(
  () => mappingProps.enableHtml,
  () => {
    md.set({
      html: mappingProps.enableHtml,
    });
    result.value = md.render(rawContent.value);
  },
);

watchEffect(async () => {
  // result.value = await marked.parse(rawContent.value);
  result.value = md.render(rawContent.value);
});

defineExpose(mappingExpose);
</script>
